package SimpleLACore

import chisel3._

class TLB extends Bundle with SimpleLACoreParam {
  val VPPN = UInt(19.W)
  val PS = UInt(6.W)
  val G = Bool()
  val ASID = UInt(10.W)
  val E = Bool()

  class P extends Bundle {
    val PPN = UInt(20.W)
    val PLV = UInt(2.W)
    val MAT = UInt(2.W)
    val D = Bool()
    val V = Bool()
  }

  val P0 = new P
  val P1 = new P

  def read()(implicit csrFile: CSRFile): Unit = {
    val tlbidx = csrFile.get(new TLBIDX)
    val tlbehi = csrFile.get(new TLBEHI)
    val tlbelo0 = csrFile.get(new TLBELO0)
    val tlbelo1 = csrFile.get(new TLBELO1)
    val asid = csrFile.get(new ASID)

    tlbidx.NE := !E
    when(E) {
      tlbidx.PS := PS
      tlbehi.VPPN := VPPN
      tlbelo0.PPN := P0.PPN
      tlbelo0.G := G
      tlbelo0.MAT := P0.MAT
      tlbelo0.PLV := P0.PLV
      tlbelo0.D := P0.D
      tlbelo0.V := P0.V
      tlbelo1.PPN := P1.PPN
      tlbelo1.G := G
      tlbelo1.MAT := P1.MAT
      tlbelo1.PLV := P1.PLV
      tlbelo1.D := P1.D
      tlbelo1.V := P1.V
      asid.ASID := ASID
    }.otherwise{
      if(set0whenNE){
        Seq(tlbidx.PS , tlbehi.VPPN, asid.ASID,
          tlbelo0.PPN, tlbelo0.G , tlbelo0.MAT, tlbelo0.PLV, tlbelo0.D , tlbelo0.V ,
          tlbelo1.PPN, tlbelo1.G , tlbelo1.MAT, tlbelo1.PLV, tlbelo1.D , tlbelo1.V).foreach(_ := 0.U)
      }
    }
  }

  def write()(implicit csrFile: CSRFile): Unit = {
    val tlbehi = csrFile.get(new TLBEHI)
    val tlbidx = csrFile.get(new TLBIDX)
    val tlbelo0 = csrFile.get(new TLBELO0)
    val tlbelo1 = csrFile.get(new TLBELO1)
    val asid = csrFile.get(new ASID)
    val estat = csrFile.get(new ESTAT)

    VPPN := tlbehi.VPPN
    PS := tlbidx.PS
    G := tlbelo0.G & tlbelo1.G
    ASID := asid.ASID
    E := Mux(estat.Ecode === 0x3F.U, 1.U, ~tlbidx.NE)
    P0.PPN := tlbelo0.PPN
    P0.PLV := tlbelo0.PLV
    P0.MAT := tlbelo0.MAT
    P0.D := tlbelo0.D
    P0.V := tlbelo0.V
    P1.PPN := tlbelo1.PPN
    P1.PLV := tlbelo1.PLV
    P1.MAT := tlbelo1.MAT
    P1.D := tlbelo1.D
    P1.V := tlbelo1.V
  }
}
